package com.gdth.widget.listview.refresh;

import com.gdth.R;
import com.gdth.model.DeleteItem;
import com.gdth.utils.DateTimeUtil;
import com.gdth.widget.listview.RefreshMode;
import com.gdth.widget.listview.adapter.SlideView;
import com.gdth.widget.listview.listener.OnLoadListener;
import com.gdth.widget.listview.listener.OnRefreshListener;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.AbsListView;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.AbsListView.OnScrollListener;

/** 
 * @author 作者 Arvin: 
 * @version 创建时间：2015年7月9日 上午10:01:41 
 * 类说明 
 */
public class RefreshListView extends ListView implements OnScrollListener{
	private Context mContext;
	private int downY;		// 按下时y轴的偏移量
	private View headerView;		// 头布局
	private int headerViewHeight;	// 头布局的高度
	private int firstVisibleItemPosition;		// 滚动时界面显示在顶部的item的position
	private RefreshMode currentState = RefreshMode.Pull;		// 头布局当前的状态, 缺省值为下拉状态
	private Animation upAnim;		// 向上旋转的动画
	private Animation downAnim;		// 向下旋转的动画
	private ImageView ivArrow;		// 头布局的箭头
	private TextView tvState;		// 头布局刷新状态
	private ProgressBar mProgressBar;	// 头布局的进度条
	private TextView tvLastUpdateTime;	// 头布局的最后刷新时间
	
	private boolean isScroll2Bottom = false;	// 是否滚动到底部
	private View footerView;		// 脚布局
	private int footerViewHeight;	// 脚布局的高度
	private boolean isLoadMoving = false;	// 是否正在加载更多中
	
	private int headerLayout = R.layout.system_listview_refresh_header;
	private int footerLayout = R.layout.system_listview_refresh_footer;

	private SlideView mFocusedItemView;
	
	private OnRefreshListener mOnRefreshListener;
	private OnLoadListener mOnLoadListener;
	
	public RefreshListView(Context context) {
		super(context);
		
		this.mContext = context;
		initView();
	}
	
	public RefreshListView(Context context, AttributeSet attrs){
		super(context, attrs);
		
		this.mContext = context;
		initView();
	}
	
	public RefreshListView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		
		this.mContext = context;
		initView();
	}
	
	private void initView(){

		initHeader();
		initFooter();
		
		initAnimation();
		
		this.setOnScrollListener(this);
	}
	
	/**
	 * 初始化脚布局
	 */
	private void initFooter() {
		footerView = LayoutInflater.from(this.mContext).inflate(footerLayout, null);
		
		measureView(footerView);		// 测量一下脚布局的高度
		
		footerViewHeight = footerView.getMeasuredHeight();
		
		footerView.setPadding(0, -footerViewHeight, 0, 0);		// 隐藏脚布局
		
		this.addFooterView(footerView);
	}

	/**
	 * 初始化头布局
	 */
	private void initHeader() {
		headerView = LayoutInflater.from(this.mContext).inflate(headerLayout, null);
		ivArrow = (ImageView) headerView.findViewById(R.id.iv_listview_header_down_arrow);
		mProgressBar = (ProgressBar) headerView.findViewById(R.id.pb_listview_header_progress);
		tvState = (TextView) headerView.findViewById(R.id.tv_listview_header_state);
		tvLastUpdateTime = (TextView) headerView.findViewById(R.id.tv_listview_header_last_update_time);
		
		ivArrow.setMinimumWidth(50);
		tvLastUpdateTime.setText("最后刷新时间: " + DateTimeUtil.getCurrentTime());
		
		measureView(headerView);
		headerViewHeight = headerView.getMeasuredHeight();
		Log.i("RefreshListView", "头布局的高度: " + headerViewHeight);
		
		headerView.setPadding(0, -headerViewHeight, 0, 0);
		
		this.addHeaderView(headerView);
	}
	
	/**
	 * 初始化动画
	 */
	private void initAnimation() {
		upAnim = new RotateAnimation(0, -180, 
				Animation.RELATIVE_TO_SELF, 0.5f, 
				Animation.RELATIVE_TO_SELF, 0.5f);
		upAnim.setDuration(500);
		upAnim.setFillAfter(true);
		
		downAnim = new RotateAnimation(
				-180, -360, 
				Animation.RELATIVE_TO_SELF, 0.5f, 
				Animation.RELATIVE_TO_SELF, 0.5f);
		downAnim.setDuration(500);
		downAnim.setFillAfter(true);
	}
	
	/**
	 * 测量给定的View的宽和高, 测量之后, 可以得到view的宽和高
	 * @param child
	 */
	private void measureView(View child) {
        ViewGroup.LayoutParams lp = child.getLayoutParams();
        if (lp == null) {
        	lp = new ViewGroup.LayoutParams(
                    ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT);
        }

        int childWidthSpec = ViewGroup.getChildMeasureSpec(0, 0, lp.width);
        
        int lpHeight = lp.height;
        int childHeightSpec;
        if (lpHeight > 0) {
            childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY);
        } else {
            childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
        }
        child.measure(childWidthSpec, childHeightSpec);
    }
	
	@Override
	public boolean onTouchEvent(MotionEvent ev) {
		switch (ev.getAction()) {
			case MotionEvent.ACTION_DOWN:
				downY = (int) ev.getY();
				
				int x = (int) ev.getX();
	            int y = (int) ev.getY();
	            int position = pointToPosition(x, y);
	            
	            if (position != INVALID_POSITION) {
	                DeleteItem data = (DeleteItem) getItemAtPosition(position);
	                mFocusedItemView = data.slideView;
	            }
	            
				break;
			case MotionEvent.ACTION_MOVE:
				// 当前的状态是正在刷新中, 不执行下拉操作
				if(currentState == RefreshMode.Refreshing)
					break;
				
				int moveY = (int) ev.getY();	// 移动中的y轴的偏移量
				int diffY = moveY - downY;
				int paddingTop = -headerViewHeight + (diffY / 2);
				
				if(firstVisibleItemPosition == 0 && paddingTop > -headerViewHeight) {
					//paddingTop > 0   完全显示
					//currentState == DisplayMode.Pull 当是在下拉状态时
					if(paddingTop > 0 && currentState == RefreshMode.Pull) {		// 完全显示, 进入到刷新状态  
						Log.i("RefreshListView", "松开刷新");
						currentState = RefreshMode.Refresh;		// 把当前的状态改为松开刷新
						refreshHeaderViewState();
					} else if(paddingTop < 0
							&& currentState == RefreshMode.Refresh) {		// 没有完全显示, 进入到下拉状态
						Log.i("RefreshListView", "下拉刷新");
						currentState = RefreshMode.Pull;
						refreshHeaderViewState();
					}
					
					headerView.setPadding(0, paddingTop, 0, 0);
					return true;
				}
				break;
			case MotionEvent.ACTION_UP:
				downY = -1;
				// 松开时, 当前显示的状态为下拉状态, 执行隐藏headerView的操作
				if(currentState == RefreshMode.Pull) {		
					headerView.setPadding(0, -headerViewHeight, 0, 0);
				} else if(currentState == RefreshMode.Refresh) {	// 松开时, 当前显示的状态为松开刷新状态, 执行刷新的操作
					headerView.setPadding(0, 0, 0, 0);
					currentState = RefreshMode.Refreshing;
					refreshHeaderViewState();
					
					if(mOnRefreshListener != null) {
						mOnRefreshListener.onRefresh();
					}
				}
				break;
	
			default:
				break;
		}
		
		if (mFocusedItemView != null) {
            mFocusedItemView.onRequireTouchEvent(ev);
        }
		
		return super.onTouchEvent(ev);
	}
	
	public void shrinkListItem(int position) {
        View item = getChildAt(position);

        if (item != null) {
            try {
                ((SlideView) item).shrink();
            } catch (ClassCastException e) {
                e.printStackTrace();
            }
        }
    }
	
	/**
	 * 当刷新任务执行完毕时, 回调此方法, 去刷新界面
	 */
	public void onRefreshFinish() {
		if(isLoadMoving) {	// 隐藏脚布局
			isLoadMoving = false;
			isScroll2Bottom = false;
			footerView.setPadding(0, -footerViewHeight, 0, 0);
		} else {	// 隐藏头布局
			headerView.setPadding(0, -headerViewHeight, 0, 0);
			mProgressBar.setVisibility(View.GONE);
			ivArrow.setVisibility(View.VISIBLE);
			tvLastUpdateTime.setText("最后刷新时间: " + DateTimeUtil.getCurrentTime());
			currentState = RefreshMode.Pull;
		}
	}
	
	/**
	 * 刷新头布局的状态
	 */
	private void refreshHeaderViewState() {
		if(currentState == RefreshMode.Pull) {	// 当前进入下拉状态
			ivArrow.startAnimation(downAnim);
			tvState.setText("下拉刷新");
		} else if(currentState == RefreshMode.Refresh) { //当前进入松开刷新状态
			ivArrow.startAnimation(upAnim);
			tvState.setText("松开刷新");
		} else if(currentState == RefreshMode.Refreshing) {  //当前进入正在刷新中
			ivArrow.clearAnimation();
			ivArrow.setVisibility(View.GONE);
			mProgressBar.setVisibility(View.VISIBLE);
			tvState.setText("正在刷新中..");
		}
	}

	/****************滑动接口*****************/
	@Override
	public void onScroll(AbsListView arg0, int arg1, int arg2, int arg3) {
		// TODO Auto-generated method stub
		firstVisibleItemPosition = arg1;
		
		if((arg1 + arg2) >= arg3 && arg3 > 0)
			isScroll2Bottom = true;
		else
			isScroll2Bottom = false;
	}

	@Override
	public void onScrollStateChanged(AbsListView arg0, int arg1) {
		// TODO Auto-generated method stub
		if(arg1 == OnScrollListener.SCROLL_STATE_IDLE || arg1 == OnScrollListener.SCROLL_STATE_FLING) {
			if(isScroll2Bottom && !isLoadMoving) {		// 滚动到底部
				// 加载更多
				footerView.setPadding(0, 0, 0, 0);
				this.setSelection(this.getCount());		// 滚动到ListView的底部
				isLoadMoving = true;
				
				if(mOnLoadListener != null) {
					mOnLoadListener.onLoad();
				}
			}
		}
	}
	
	/******************接口*****************/
	/**
	 * 设置刷新的监听事件
	 * @param listener
	 */
	public void setOnRefreshListener(OnRefreshListener listener) {
		this.mOnRefreshListener = listener;
	}
	
	public void setOnLoadListener(OnLoadListener listener) {
		this.mOnLoadListener = listener;
	}
}
